"use strict";
/**
 * @name like
 * 好感度系统
 */
const LIKE_LV_RECORD_PREFIX = "likeLv";
const LIKE_EXP_RECORD_PREFIX = "likeExp";
exports.LIKE_LV_RECORD_PREFIX = LIKE_LV_RECORD_PREFIX;
exports.LIKE_EXP_RECORD_PREFIX = LIKE_EXP_RECORD_PREFIX;
exports.updateMood = updateMood;
exports.updateExp = updateExp;
/**
 * @name likeUp
 * @param string key 唯一ID
 * @param json costData 消耗物品 json格式 物品id:num
 * 增加好感度
 */
exports.likeUp = async function () {
    try {
        const costData = this.get('costData', 'json');
        const key = this.get('key', 'string');
        if (!costData || !key) {
            return this.quick_error('M2saghge140', ' 参数错误');
        }
        this.updater.item.key(key);
        this.updater.daily.key('likeTime.' + key);
        await this.updater.data();
        const unit = getUnit.call(this, key);
        //获取角色的好感度等级和经验
        this.updater.record.key(LIKE_LV_RECORD_PREFIX + unit.id);
        this.updater.record.key(LIKE_EXP_RECORD_PREFIX + unit.id);
        await this.updater.data();
        let lexp = this.updater.record.get(LIKE_EXP_RECORD_PREFIX + unit.id) || 0;
        let llv = this.updater.record.get(LIKE_LV_RECORD_PREFIX + unit.id) || 0;
        const preferItemConfig = getPreferItemConfig.call(this, unit);
        const { expNum, moodNum } = calculateExpAndMood.call(this, costData, preferItemConfig);
        updateMood.call(this, unit, moodNum);
        updateExp.call(this, unit.id, lexp, llv, expNum);
        this.updater.item.set(unit._id, "mood", unit.mood);
        this.updater.daily.add('likeTime.' + unit.id, 1);
        return this.updater.save();
    } catch (err) {
        return err;
    }
}

/**
 * @name touchUnit
 * @param int id 好感度组ID
 * 触摸增加好感度
 */
exports.touchUnit = async function () {
    try {
        const id = this.get('id', 'int');
        this.updater.daily.key('touchTime');
        await this.updater.data();
        this.updater.record.key(LIKE_LV_RECORD_PREFIX + id);
        this.updater.record.key(LIKE_EXP_RECORD_PREFIX + id);
        await this.updater.data();
        let lexp = this.updater.record.get(LIKE_EXP_RECORD_PREFIX + id) || 0;
        let llv = this.updater.record.get(LIKE_LV_RECORD_PREFIX + id) || 0;
        const touchTime = this.updater.daily.get('touchTime') || 0;
        const maxTime = this.config('base', 'touchMaxTimes').val;
        if (touchTime >= maxTime) {
            return;
        }
        this.updater.daily.add('touchTime', 1);
        const touchFavorability = this.config('base', 'touchFavorability').val;
        updateExp.call(this, id, lexp, llv, touchFavorability);
        this.updater.daily.add(`likeTime.${id}`, 1);
        return this.updater.save();
    } catch (err) {
        return err;
    }
}

/**
 * @name getLikeReward
 * @param int id 好感度组ID
 * 获取好感度奖励
 */
exports.getLikeReward = async function () {
    const id = this.get('id', 'int');
    if (!id) {
        return this.quick_error("M2saghge10", "参数缺失key");
    }
    const unitConfig = this.config('unit', id);
    if (!unitConfig) {
        return this.quick_error("M2saghge40", "角色数据不存在", id);
    }
    const likeLvRecordKey = LIKE_LV_RECORD_PREFIX + id;
    this.updater.record.key(likeLvRecordKey);
    this.updater.role.key("unitLikeReward." + id);
    await this.updater.data();
    const unitLikeReward = this.updater.role.get("unitLikeReward." + id) || 0;
    const likeLv = await this.updater.record.get(likeLvRecordKey, 'val');
    if (likeLv <= unitLikeReward) {
        return this.quick_error("M2saghge40", "无奖励可领");
    }
    const likeRewardConfig = this.config('likeExp');
    if (!likeRewardConfig) {
        return this.quick_error("M2saghge50", "消耗配置不存在");
    }
    for (const reward of Object.values(likeRewardConfig)) {
        if (reward.lv <= likeLv && unitLikeReward < reward.lv) {
            switch (unitConfig.rare) {
                case 2:
                    this.updater.item.add(reward.oneStarGift, 1);
                    break;
                case 4:
                    this.updater.item.add(reward.twoStarGift, 1);
                    break;
                case 6:
                    this.updater.item.add(reward.threeStarGift, 1);
                    break;
                default:
                    continue;
            }
        }
    }
    this.updater.role.set("unitLikeReward." + id, likeLv);
    return this.updater.save();
}



function getUnit(key) {
    let unit = this.updater.item.get(key);
    if (!unit) {
        throw this.quick_error("M2saghge20", "角色不存在", key);
    }
    const unitConfig = this.config('unit', unit.id);
    if (!unitConfig) {
        throw this.quick_error("M2saghge40", "角色数据不存在", unit.id);
    }
    unit.eggType = unitConfig.race;
    return unit;
}

function getPreferItemConfig(unit) {
    const preferItemConfig = this.config('preferItem', unit.eggType);
    if (!preferItemConfig) {
        throw this.quick_error("M2saghge40", "角色数据不存在", unit.id);
    }
    return preferItemConfig;
}

function calculateExpAndMood(costData, preferItemConfig) {
    let expNum = 0;
    let moodNum = 0;
    for (let [id, count] of Object.entries(costData)) {
        const giftConfig = this.config('unitGiftItem', id);
        if (!giftConfig) {
            throw this.quick_error("M2saghge50", "消耗配置不存在", id);
        }
        const flag = preferItemConfig.giftID.includes(parseInt(id)) ? 2 : 1;
        expNum += giftConfig.addExp * count * flag;
        moodNum += giftConfig.addMood * count;
        this.updater.item.sub(parseInt(id), count);
    }
    return { expNum, moodNum };
}

function updateMood(unit, moodNum) {
    const time = Date.now();
    const MOOD_MAX = this.config('base', 'moodMaxValue').val;
    const MOOD_ADD_SPEED = this.config('base', 'moodAddSpeed').val * 1000;
    if (unit.mood.val < MOOD_MAX) {
        const sub = time - unit.mood.time;
        const autoAddMood = parseInt(sub / MOOD_ADD_SPEED);
        if (autoAddMood > 0) {
            unit.mood.val = Math.min(unit.mood.val + autoAddMood, MOOD_MAX);
            unit.mood.time = time;
        }
    }
    unit.mood.val = Math.min(unit.mood.val + moodNum, MOOD_MAX);
}
//BUG:调用此函数的地方会有潜在bug，循环写入record可能会导致数据覆盖，使用时要注意
//更新好感度
function updateExp(id, lexp, llv, expNum) {
    const unitConfig = this.config('unit', id);
    if (!unitConfig) {
        throw this.quick_error("M2saghge40", "角色数据不存在", id);
    }
    if (unitConfig.giftGroup === -1) {
        return;
    } else if (unitConfig.giftGroup !== 0) {
        id = unitConfig.giftGroup;
    }
    const expConfig = this.config('likeExp');
    if (!expConfig) {
        throw this.quick_error("M2saghge50", "消耗配置不存在");
    }
    // let baseExp = lexp
    let totalExp = lexp + expNum
    // let useExpNum = 0;
    let upLvFlag = false;
    let upExpFlag = false;
    const ROLE_LV_MAX = Object.keys(expConfig).length;
    for (let i = llv + 1; i <= ROLE_LV_MAX; i++) {
        if (expConfig[i].lv >= llv) {
            if (totalExp - expConfig[i].exp < 0) {
                // useExpNum += totalExp;
                lexp = totalExp;
                upExpFlag = true;
                break;
            } else {
                llv++;
                upLvFlag = true;
                totalExp -= expConfig[i].exp
                // useExpNum += expConfig[i].exp;
                lexp = 0;
            }
        }
    }
    // if ((useExpNum - baseExp) < 0) {
    //     throw this.quick_error("M2saghge50", "啥事没干", useExpNum - baseExp);
    // }
    if (upExpFlag) {
        this.updater.record.set(LIKE_EXP_RECORD_PREFIX + id, lexp);
    }
    if (upLvFlag) {
        this.updater.record.max(LIKE_LV_RECORD_PREFIX + id, llv);
    }
}

